home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / oleo-1_4.lha / oleo-1.4 / string.c < prev    next >
C/C++ Source or Header  |  1993-05-13  |  7KB  |  355 lines

  1. /*    Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This file is part of Oleo, the GNU Spreadsheet.
  4.  
  5. Oleo is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. Oleo is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with Oleo; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ctype.h>
  20. #include "funcdef.h"
  21. #define obstack_chunk_alloc ck_malloc
  22. #define obstack_chunk_free free
  23. #include "obstack.h"
  24. #include "sysdef.h"
  25.  
  26. #include "global.h"
  27. #include "cell.h"
  28. #include "eval.h"
  29. #include "errors.h"
  30.  
  31. struct value {
  32.     int    type;
  33.     union vals x;
  34. };
  35.  
  36. #define Float    x.c_d
  37. #define String    x.c_s
  38. #define Int    x.c_l
  39. #define Value    x.c_i
  40. #define Rng    x.c_r
  41.  
  42. #define ERROR(x)    \
  43.  {            \
  44.     p->Value=x;    \
  45.     p->type=TYP_ERR;\
  46.     return;        \
  47.  }
  48.     
  49.  
  50. extern struct obstack tmp_mem;
  51.  
  52. extern char *flt_to_str();
  53.  
  54. static void
  55. do_edit (numarg,p)
  56.      int numarg;
  57.       struct value * p;
  58. {
  59.     int mm;
  60.     int add_len;
  61.     int tmp_len;
  62.     char *ptr1,*ptr2,*retp;
  63.     int off1,off2;
  64.  
  65.     if(numarg<3)
  66.         ERROR(BAD_INPUT);
  67.     for(mm=3,add_len=0;mm<numarg;mm++)
  68.         add_len+=strlen((p+mm)->String);
  69.     tmp_len=strlen(p->String);
  70.     off1=(p+1)->Int;
  71.     off2=(p+2)->Int;
  72.     if(off1==0 || tmp_len < ((off1<0) ? -off1 : off1) ||
  73.        off2==0 || tmp_len < ((off2<0) ? -off2 : off2))
  74.         ERROR(OUT_OF_RANGE);
  75.     ptr1=p->String + (off1>0 ? off1-1 : tmp_len+off1);
  76.     ptr2=p->String + 1 + (off2>0 ? off2-1 : tmp_len+off2);
  77.     if(ptr1>ptr2)
  78.         ERROR(OUT_OF_RANGE);
  79.     retp=obstack_alloc(&tmp_mem,add_len+tmp_len-(ptr2-ptr1));
  80.     strncpy(retp,p->String,ptr1-p->String);
  81.     retp[ptr1-p->String]='\0';
  82.     for(mm=3;mm<numarg;mm++)
  83.         strcat(retp,(p+mm)->String);
  84.     strcat(retp,ptr2);
  85.     p->String=retp;
  86.     p->type=TYP_STR;
  87. }
  88.  
  89. static void
  90. do_repeat (p)
  91.      struct value * p;
  92. {
  93.     char *str = (p  )->String;
  94.     long num  = (p+1)->Int;
  95.  
  96.     char *ret;
  97.     char *strptr;
  98.     int len;
  99.  
  100.     if(num<0)
  101.         ERROR(OUT_OF_RANGE);
  102.     len=strlen(str);
  103.     ret=strptr=obstack_alloc(&tmp_mem,len*num+1);
  104.     while(num--) {
  105.         if (len)
  106.           bcopy(str,strptr,len);
  107.         strptr+=len;
  108.     }
  109.     *strptr=0;
  110.     p->String=ret;
  111. }
  112.  
  113. static void
  114. do_len (p)
  115.      struct value * p;
  116. {
  117.     long ret;
  118.     char *ptr;
  119.  
  120.     for(ret=0,ptr=p->String;*ptr;ret++,ptr++)
  121.         ;
  122.     p->Int=ret;
  123.     p->type=TYP_INT;
  124. }
  125.  
  126. static void
  127. do_up_str (p)
  128.      struct value * p;
  129. {
  130.     char *s1,*s2;
  131.     char *strptr;
  132.  
  133.     strptr=obstack_alloc(&tmp_mem,strlen(p->String)+1);
  134.     for(s1=strptr,s2=p->String;*s2;s2++)
  135.         *s1++ = (islower(*s2) ? toupper(*s2) : *s2);
  136.     *s1=0;
  137.     p->String=strptr;
  138. }
  139.  
  140. static void
  141. do_dn_str (p)
  142.      struct value * p;
  143. {
  144.     char *s1,*s2;
  145.     char *strptr;
  146.  
  147.     strptr=obstack_alloc(&tmp_mem,strlen(p->String)+1);
  148.     for(s1=strptr,s2=p->String;*s2;s2++)
  149.         *s1++ = (isupper(*s2) ? tolower(*s2) : *s2);
  150.     *s1=0;
  151.     p->String=strptr;
  152. }
  153.  
  154. static void
  155. do_cp_str (p)
  156.      struct value * p;
  157. {
  158.     char *strptr;
  159.     char *s1,*s2;
  160.     int wstart=1;
  161.  
  162.     strptr=obstack_alloc(&tmp_mem,strlen(p->String)+1);
  163.     for(s1=strptr,s2=p->String;*s2;s2++) {
  164.         if(!isalpha(*s2)) {
  165.             wstart=1;
  166.             *s1++= *s2;
  167.         } else if(wstart) {
  168.             *s1++ = (islower(*s2) ? toupper(*s2) : *s2);
  169.             wstart=0;
  170.         } else
  171.             *s1++ = (isupper(*s2) ? tolower(*s2) : *s2);
  172.     }
  173.     *s1=0;
  174.     p->String=strptr;
  175. }
  176.  
  177. static void
  178. do_trim_str (p)
  179.      struct value * p;
  180. {
  181.     char *s1,*s2;
  182.     int sstart=0;
  183.     char *strptr;
  184.  
  185.     strptr=obstack_alloc(&tmp_mem,strlen(p->String)+1);
  186.     for(s1=strptr,s2=p->String;*s2;s2++) {
  187.         if(!isascii(*s2) || !isprint(*s2))
  188.             continue;
  189.         if(*s2==' ') {
  190.                 if(sstart) {
  191.                 *s1++= *s2;
  192.                 sstart=0;
  193.             }
  194.         } else {
  195.             sstart=1;
  196.             *s1++= *s2;
  197.         }
  198.     }
  199.     *s1=0;
  200.     p->String=strptr;
  201. }
  202.  
  203. static void
  204. do_concat ( numarg,p)
  205.      int  numarg;
  206.       struct value * p;
  207. {
  208.     int cur_string;
  209.     char *s;
  210.     char buf[40];
  211.     CELLREF crow,ccol;
  212.     CELL *cell_ptr;
  213.  
  214.     for(cur_string=0;cur_string<numarg;cur_string++) {
  215.         switch(p[cur_string].type) {
  216.         case 0:
  217.             continue;
  218.         case TYP_RNG:
  219.             for(crow=p[cur_string].Rng.lr;crow<=p[cur_string].Rng.hr;crow++)
  220.                 for(ccol=p[cur_string].Rng.lc;ccol<=p[cur_string].Rng.hc;ccol++) {
  221.                     if(!(cell_ptr=find_cell(crow,ccol)))
  222.                         continue;
  223.                     switch(GET_TYP(cell_ptr)) {
  224.                     case 0:
  225.                         break;
  226.                     case TYP_STR:
  227.                         (void)obstack_grow(&tmp_mem,cell_ptr->cell_str,strlen(cell_ptr->cell_str));
  228.                         break;
  229.                     case TYP_INT:
  230.                         sprintf(buf,"%ld",cell_ptr->cell_int);
  231.                         (void)obstack_grow(&tmp_mem,buf,strlen(buf));
  232.                         break;
  233.                     case TYP_FLT:
  234.                         s=flt_to_str(cell_ptr->cell_flt);
  235.                         (void)obstack_grow(&tmp_mem,s,strlen(s));
  236.                         break;
  237.                     default:
  238.                         (void)obstack_finish(&tmp_mem);
  239.                         ERROR(NON_STRING);
  240.                     }
  241.             }
  242.             break;
  243.         case TYP_STR:
  244.             s=p[cur_string].String;
  245.             (void)obstack_grow(&tmp_mem,s,strlen(s));
  246.             break;
  247.         case TYP_INT:
  248.             sprintf(buf,"%ld",p[cur_string].Int);
  249.             (void)obstack_grow(&tmp_mem,buf,strlen(buf));
  250.             break;
  251.         case TYP_FLT:
  252.             s=flt_to_str(p[cur_string].Float);
  253.             (void)obstack_grow(&tmp_mem,s,strlen(s));
  254.             break;
  255.         default:
  256.             (void)obstack_finish(&tmp_mem);
  257.             ERROR(NON_STRING);
  258.         }
  259.     }
  260.     (void)obstack_1grow(&tmp_mem,0);
  261.     p->type=TYP_STR;
  262.     p->String=(char *)obstack_finish(&tmp_mem);
  263. }
  264.  
  265.  
  266. static void
  267. do_mid (p)
  268.      struct value * p;
  269. {
  270.     char *str = (p  )->String;
  271.     long from = (p+1)->Int;
  272.     long len =  (p+2)->Int;
  273.  
  274.     char    *ptr1;
  275.     int tmp;
  276.  
  277.     tmp=strlen(str);
  278.  
  279.     if(from<0 || len<0)
  280.         ERROR(OUT_OF_RANGE);
  281.     ptr1=(char *)obstack_alloc(&tmp_mem,len+1);
  282.     if(from>=tmp || len==0)
  283.         ptr1[0]='\0';
  284.     else {
  285.         strncpy(ptr1,str+from,len);
  286.         ptr1[len]='\0';
  287.     }
  288.     p->String=ptr1;
  289. }
  290.  
  291.  
  292. static void
  293. do_substr (p)
  294.      struct value * p;
  295. {
  296.     long off1 = (p  )->Int;
  297.     long off2 = (p+1)->Int;
  298.     char *str = (p+2)->String;
  299.  
  300.     char    *ptr1,    *ptr2;
  301.     int tmp;
  302.     char *ret;
  303.  
  304.     tmp=strlen(str);
  305.     if(off1==0 || tmp < ((off1<0) ? -off1 : off1) ||
  306.        off2==0 || tmp < ((off2<0) ? -off2 : off2))
  307.         ERROR(OUT_OF_RANGE);
  308.     ptr1=str + (off1>0 ? off1-1 : tmp+(off1));
  309.     ptr2=str + (off2>0 ? off2-1 : tmp+(off2));
  310.  
  311.     if(ptr1>ptr2)
  312.         ERROR(OUT_OF_RANGE);
  313.     tmp=(ptr2-ptr1)+1;
  314.     ret=(char *)obstack_alloc(&tmp_mem,tmp+1);
  315.     strncpy(ret,ptr1,tmp);
  316.     ret[tmp]=0;
  317.     p->String=ret;
  318.     p->type=TYP_STR;
  319. }
  320.  
  321. static void
  322. do_strstr (p)
  323.      struct value * p;
  324. {
  325.     char *str1    = (p  )->String;
  326.     char *strptr    = (p+1)->String;
  327.     long off    = (p+2)->Int;
  328.     char *ret;
  329.  
  330.     if(off<1 || strlen(strptr)<=off-1)
  331.         ERROR(OUT_OF_RANGE);
  332.     ret=(char *)strstr(strptr+off-1,str1);
  333.     p->Value= ret ? 1 + ret-strptr : 0;
  334.     p->type=TYP_INT;
  335. }
  336.  
  337. struct function string_funs[] = {
  338. { C_FN1,    X_A1,    "S",    do_len,        "len" },
  339. { C_FN3,    X_A3,    "SSI",  do_strstr,    "find" },
  340.  
  341. { C_FN1,    X_A1,    "S",    do_up_str,    "strupr" },
  342. { C_FN1,    X_A1,    "S",    do_dn_str,    "strlwr" },
  343. { C_FN1,    X_A1,    "S",    do_cp_str,    "strcap" },
  344. { C_FN1,    X_A1,    "S",    do_trim_str,    "trim" },
  345.  
  346. { C_FN3,    X_A3,    "IIS",  do_substr,    "substr" },
  347. { C_FN3,    X_A3,    "SII",  do_mid,        "mid" },
  348.  
  349. { C_FN2,    X_A2,    "SI",   do_repeat,    "repeat" },
  350. { C_FNN,    X_AN,    "EEEE", do_concat,    "concat" },
  351. { C_FNN,    X_AN,    "SIIS", do_edit,    "edit" },
  352. { 0,        0,    {0},    0,        0 }
  353. };
  354.  
  355.